/*
 * @(#)GsLoginSuccessHandler.java
 * 2011-5-15 下午12:21:14
 *
 * Copyright (c) 2018-2028, HangZhou QiYun InfoTech Co.,Ltd. .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.qyxx.platform.sysmng.accountmng.service;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.transaction.annotation.Transactional;

import com.opensymphony.xwork2.interceptor.I18nInterceptor;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.qyxx.platform.common.module.web.FormatMessage;
import com.qyxx.platform.common.utils.web.ServletUtils;
import com.qyxx.platform.sysmng.accountmng.dao.OnlineUserDao;
import com.qyxx.platform.sysmng.accountmng.dao.RoleDao;
import com.qyxx.platform.sysmng.accountmng.dao.UserDao;
import com.qyxx.platform.sysmng.accountmng.entity.OnlineUser;
import com.qyxx.platform.sysmng.accountmng.entity.Organization;
import com.qyxx.platform.sysmng.accountmng.entity.Role;
import com.qyxx.platform.sysmng.accountmng.entity.User;
import com.qyxx.platform.sysmng.logmng.entity.Log;
import com.qyxx.platform.sysmng.logmng.web.LogInfoThreadPool;
import com.qyxx.platform.sysmng.utils.Constants;


/**
 *  登录成功处理器
 *  
 *  设置用户session及用户相关的配置信息，记录登录日志及在线用户列表
 *  @author gxj
 *  @version 1.0
 *  @since 1.6 2011-5-15 下午12:21:14
 */
@Transactional
public class GsLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
	
	private static final String FIND_DATA_RESOURCE_HQL = "select a.resourceUrl"
		+ " from Authority a inner join a.roleList b where"
		+ " b.id in (select e.id from User d inner join d.roleList e where d.id = ?)"
		+ " and a.resourceType = ? and a.resourceStatus = ? and b.roleStatus = ?";

	private UserDao userDao;
	
	private RoleDao roleDao;
	
	private OnlineUserDao onlineUserDao;
	
	private LogInfoThreadPool logInfoThreadPool;

	/**
	 * @param userDao
	 */
	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	/**
	 * @param onlineUserDao
	 */
	@Autowired
	public void setOnlineUserDao(OnlineUserDao onlineUserDao) {
		this.onlineUserDao = onlineUserDao;
	}

	/**
	 * @param roleDao
	 */
	@Autowired
	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	/**
	 * @param logInfoThreadPool
	 */
	@Autowired
	public void setLogInfoThreadPool(LogInfoThreadPool logInfoThreadPool) {
		this.logInfoThreadPool = logInfoThreadPool;
	}

	@Transactional
	@Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws ServletException, IOException {
		//TODO 准备工作
		UserDetails userDetails = (UserDetails) authentication.getPrincipal();
		String name = userDetails.getUsername();
		Date date = new Date();
		
		User user = this.userDao.findUniqueBy("loginName", name);
		if(null != user) {
			//记录在线用户
			OnlineUser ou = new OnlineUser();
			ou.setId(null);
			String ipAddr = ServletUtils.getIpAddr(request);
			ou.setLoginIp(ipAddr);
			ou.setLoginMachine(request.getRemoteHost());
			ou.setLoginUsername(user.getLoginName());
			ou.setLoginTime(date);
			ou.setUser(user);
			HttpSession session = request.getSession();
			ou.setSessionId(session.getId());
			onlineUserDao.save(ou);
			
			//查询数据权限，记录在用户session中
			List<String> dataAuthList = userDao.find(FIND_DATA_RESOURCE_HQL, user.getId(), 
					Constants.RESOURCE_TYPE_DATA, Constants.ENABLED, Constants.ENABLED);
			user.setDataAuthList(dataAuthList);
			//可见用户列表
			Map<String, Map<String,List<Long>>> seeUserIdList = userDao.findSeeUserByUserId(user.getId());
			user.setSeeUserIdMap(seeUserIdList);
			//字段条件可见列表
			user.setFieldCondMap(userDao.findFieldCondByUserId(user.getId()));
			
			Organization org = user.getOrganization();
			if(null!=org) {
				user.setOrgCode(org.getOrganizationCode());
			}
			//查询角色对应首页及门户url地址
			List<Role> roleList = roleDao.findRoleUrlByUserId(user.getId(), Constants.ENABLED);
			if(null!=roleList && !roleList.isEmpty()) {
				for(Role role:roleList) {
					String indexUrl = role.getIndexUrl();
					if(StringUtils.isNotBlank(indexUrl)) {
						user.setIndexUrl(indexUrl);
					}
					String portalUrl = role.getPortalUrl();
					if(StringUtils.isNotBlank(portalUrl)) {
						user.setPortalUrl(portalUrl);
					}
				}				
			}
			
			//去除session关联
			userDao.evict(user);
			user.setRoleList(roleList);
			//记录Session
			//locale = (String)session.getAttribute(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE);
			//logger.info("当前Session语言环境：" + locale);
			String locale = request.getParameter(Constants.REQUEST_LOCALE);
			//logger.info("当前Request语言环境：" + locale);
			session.setAttribute(Constants.USER_SESSION_ID, user);
			session.setAttribute(Constants.LOCALE_SESSION_ID, locale);
			//设置i18n拦截器默认取的属性
			Locale local = LocalizedTextUtil.localeFromString(locale, null);
			//logger.info("设置session语言环境" + locale);
			session.setAttribute(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, local);
			session.setAttribute(Constants.THEME_STYLE_SESSION_ID, Constants.DEFAULT_THEME_STYLE);
			session.setAttribute(Constants.THEME_COLOR_SESSION_ID, Constants.DEFAULT_THEME_COLOR);
			
			session.setAttribute("fr_username", user.getLoginName());
			session.setAttribute("fr_userid", user.getId());
			
			//记录用户名cookie
			Cookie userCookie = new Cookie(Constants.USER_NAME_COOKIE, java.net.URLEncoder.encode(name, Constants.DEFAULT_ENCODE));
			userCookie.setPath("/");
			userCookie.setMaxAge(Constants.USER_NAME_COOKIE_MAX_AGE);
			response.addCookie(userCookie);
			
			//记录日志
			String url = UrlUtils.buildRequestUrl(request);
			//logger.info("日志拦截器拦截url为：" + url);
			String operName = Constants.LOGIN_MESSAGE;
			String operDesc = Constants.LOGIN_MESSAGE;
			Log log = new Log();
			log.setOperationUrl(url);
			log.setLoginName(user.getLoginName());
			log.setRealName(user.getRealName());
			log.setIp(ipAddr);
			log.setMachineName(request.getRemoteHost());
			String method = "login";
			log.setOperationMethod(method);
			log.setOperationName(operName);
			log.setOperationDesc(operDesc);
			//添加组织名称
			log.setOrgName(user.getOrganizationName());
			log.setOperationTime(date);
			log.setRemark(request.getHeader("User-Agent"));
			logInfoThreadPool.addLog(log);
		} else {
			throw new AccessDeniedException("登录名为" + name + "的用户已经被禁用或者删除，请联系系统管理员");
		}
		//自定义重定向策略，支持ajax请求
		AjaxRedirectStrategy art = new AjaxRedirectStrategy();
		FormatMessage fm = new FormatMessage();
		fm.setMsg(user);
		art.setFm(fm);
		this.setRedirectStrategy(art);
		super.onAuthenticationSuccess(request, response, authentication);
	}
	
}
